package net.whzjkj.gateway.core.util;

import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * @description: JT808转译工具类
 * @author: Mr.Hu
 * @create: 2018-10-31 15:55
 **/
@Slf4j
public class JT808ProtocolUtils {


    /**
     * 接收消息转译
     * 若校验码、消息头、消息体
     * 转译还原->验证校验码->解析消息
     * @param data        消息数据
     * @return
     */
    public static byte[] translationReceive(byte[] data) throws IOException {
        ByteArrayOutputStream out = null;
        try {
            out = new ByteArrayOutputStream();
            for (int i=0, len=data.length;i<len;i++){
                if (i<len-1 && data[i]==0x7d&&data[i+1]==0x01){
                    out.write(0x7d);
                    i++;
                }else if (i<len-1 && data[i]==0x7d&&data[i+1]==0x02){
                    out.write(0x7e);
                    i++;
                }else{
                    out.write(data[i]);
                }
            }
            return out.toByteArray();
        } catch (Exception e){
            throw e;
        } finally {
            if (out!=null){
                out.close();
            }
        }
    }

    /**
     * 发送消息转译
     * 消息封装->填充校验码->转译
     * @param data
     * @return
     */
    public static byte[] translationSend(byte[] data) throws IOException {
        ByteArrayOutputStream out = null;
        try {
            out = new ByteArrayOutputStream();
            for (int i = 0, len = data.length; i<len; i++){
                if (data[i]==0x7e){
                    out.write(0x7d);
                    out.write(0x02);
                }else if(data[i]==0x7d){
                    out.write(0x7d);
                    out.write(0x01);
                }else{
                    out.write(data[i]);
                }
            }
            return out.toByteArray();
        }catch (Exception e){
            throw e;
        }finally {
            if (out!=null){
                out.close();
            }
        }
    }


    /**
     * 生成消息头
     * @param messageId
     * @param messageBodyProperty
     * @param terminalPhone
     * @param messageFlowNo
     * @return
     */
    public static byte[] generateMessageHeader(int messageId, int messageBodyProperty, String terminalPhone, int messageFlowNo) throws IOException {
        ByteArrayOutputStream out = null;
        try {
            out = new ByteArrayOutputStream();
            out.write(ByteUtils.integerTo2Byte(messageId));
            out.write(ByteUtils.integerTo2Byte(messageBodyProperty));
            out.write(BCD8421Utils.string2Bcd(terminalPhone));
            out.write(ByteUtils.integerTo2Byte(messageFlowNo));
            return out.toByteArray();
        } catch (IOException e) {
            throw e;
        } finally {
            if (out!=null){
                out.close();
            }
        }
    }

    /**
     * 生成消息体属性
     * @param messageBodyLength
     * @param encryptionType
     * @param hasSubPackage
     * @param reservedBit
     * @return
     */
    public static int generateMessageBodyProperty(int messageBodyLength, int encryptionType, boolean hasSubPackage, int reservedBit){
        if (messageBodyLength>=1024){
            log.error("The max value of msgLen is 1023, but {} .", messageBodyLength);
        }
        // [ 0-9 ] 0000,0011,1111,1111(3FF)(消息体长度)
        int subPackage = hasSubPackage?1:0;
        // [10-12] 0001,1100,0000,0000(1C00)(加密类型)
        // [ 13_ ] 0010,0000,0000,0000(2000)(是否有子包)
        // [14-15] 1100,0000,0000,0000(C000)(保留位)
        return ((messageBodyLength & 0x3FF) |
                ((encryptionType << 10) & 0x1C00) |
                ((subPackage << 13) & 0x2000) |
                ((reservedBit << 14) & 0xC000)) & 0xffff;
    }
}
